package com.hcc.gateway.netty.server;

import cn.hutool.core.util.StrUtil;
import com.hcc.gateway.netty.config.GatewayConfig;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
 * HccGatewayNettyServer
 *
 * @author hushengjun
 * @date 2021/12/25
 */
@Slf4j
public class GatewayServer {

    private final EventLoopGroup bossEventLoopGroup;
    private final EventLoopGroup workerEventLoopGroup;

    private final GatewayConfig config;

    public GatewayServer(GatewayConfig config) {
        this.config = config;
        bossEventLoopGroup = new NioEventLoopGroup(config.getBossThreads());
        workerEventLoopGroup = new NioEventLoopGroup(config.getWorkerThreads());
    }

    public void start() {
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossEventLoopGroup, workerEventLoopGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(new GatewayServerInitializer(config));

            ChannelFuture channelFuture;
            if (StrUtil.isEmpty(config.getHost())) {
                channelFuture = serverBootstrap.bind(config.getPort()).sync();
            } else {
                channelFuture = serverBootstrap.bind(config.getHost(), config.getPort()).sync();
            }
            channelFuture.addListener(future -> {
                if (channelFuture.isSuccess()) {
                    log.info("hcc-gateway启动成功！host: {}, port: {}", config.getHost(), config.getPort());
                }
            });
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("hcc-gateway启动失败！", e);
        } finally {
            bossEventLoopGroup.shutdownGracefully();
            workerEventLoopGroup.shutdownGracefully();
        }
    }

    public void shutdown() {
        bossEventLoopGroup.shutdownGracefully();
        workerEventLoopGroup.shutdownGracefully();
    }

}
